#include <muduo/net/TcpServer.h>
#include <muduo/base/Logging.h>
#include <boost/bind.hpp>
#include <muduo/net/EventLoop.h>
#include "sqlpc.hpp"
#include "Zibprotol.hpp"
#include <unordered_map>

class EchoServer
{
public:
    EchoServer(muduo::net::EventLoop *loop,
               const muduo::net::InetAddress &listenAddr);

    void start();

private:
    void onConnection(const muduo::net::TcpConnectionPtr &conn);

    void onMessage(const muduo::net::TcpConnectionPtr &conn,
                   muduo::net::Buffer *buf,
                   muduo::Timestamp time);

    muduo::net::TcpServer server_;

    double sendingInterval_;                                                                 // 发送间隔（秒）
    std::unordered_map<muduo::net::TcpConnectionPtr, bool> inStreamingMode_;                 // 是否进入持续发送模式的标记
    std::unordered_map<muduo::net::TcpConnectionPtr, muduo::net::TimerId> connectionTimers_; // 存储每个连接的定时器ID
    std::vector<muduo::net::TcpConnectionPtr> dt;
    Data_get dd;

private:
    void startStreamingToClient(const muduo::net::TcpConnectionPtr &conn);
    void sendStreamingDataToClient(const muduo::net::TcpConnectionPtr &conn);
};

EchoServer::EchoServer(muduo::net::EventLoop *loop,
                       const muduo::net::InetAddress &listenAddr)
    : server_(loop, listenAddr, "EchoServer"),
      sendingInterval_(2.0)
{
    dd.InitSql();
    server_.setConnectionCallback(
        boost::bind(&EchoServer::onConnection, this, _1));
    server_.setMessageCallback(
        boost::bind(&EchoServer::onMessage, this, _1, _2, _3));
}

void EchoServer::start()
{
    server_.start();
}

void EchoServer::onConnection(const muduo::net::TcpConnectionPtr &conn)
{
    if (conn->connected())
    {
        LOG_INFO << "New connection from " << conn->peerAddress().toIpPort();
        // 初始时不在持续发送模式
        inStreamingMode_[conn] = false;
    }
    else
    {
        LOG_INFO << "Connection disconnected from " << conn->peerAddress().toIpPort();
        // 取消定时器
        auto it = connectionTimers_.find(conn);
        if (it != connectionTimers_.end())
        {
            it->first->getLoop()->cancel(it->second);
            connectionTimers_.erase(it);
        }
        // 清除持续发送模式标记
        inStreamingMode_.erase(conn);
    }
}

void EchoServer::onMessage(const muduo::net::TcpConnectionPtr &conn,
                           muduo::net::Buffer *buf,
                           muduo::Timestamp time)
{
    // 接收到所有的消息，然后回显
    std::string msg(buf->retrieveAllAsString());
    LOG_INFO << "Received message from " << conn->peerAddress().toIpPort() << ": " << msg;

    Zibprotol zz;

    if (zz.jgcfrom(msg) == 0)
    {
        LOG_INFO << "msg error";
        return;
    }
    else if (zz.jgcfrom(msg) == 1)
    {
        dt.push_back(conn);
        auto sensor_data = zz.parseData(msg);
        for (const auto &data : sensor_data)
        {
            std::cout << "Temperature: " << data.temp << ", Humidity: " << data.humi << std::endl;
            dd.Savedata(data.humi, data.temp);
        }
    }
    else if (zz.jgcfrom(msg) == 2)
    {
        // 检查是否是首次消息，并决定是否进入持续发送模式
        if (inStreamingMode_[conn] == false) // 首次消息
        {
            // 根据消息格式进行判断（这里假设某种特定格式表示需要进入持续发送模式）

            inStreamingMode_[conn] = true;
            startStreamingToClient(conn);
        }
        else if (inStreamingMode_[conn] == true) // 如果已经在持续发送模式，则继续发送数据（这里省略实际发送逻辑，仅作为示例）
        {
            // ...（发送数据的逻辑，例如从数据库获取数据并发送）
            // 注意：这里应该有一个实际的发送逻辑，而不是仅仅打印日志
            for (auto i : dt)
            {
                if (i->connected())
                    i->send("Streaming data...");
            }
        }
    }
    else if (zz.jgcfrom(msg) == 3)
    {
        
    }

    // conn->send(msg);
}

void EchoServer::startStreamingToClient(const muduo::net::TcpConnectionPtr &conn)
{
    // 设置定时器，定期向客户端发送数据
    connectionTimers_[conn] = conn->getLoop()->runEvery(sendingInterval_, boost::bind(&EchoServer::sendStreamingDataToClient, this, conn));
}
void EchoServer::sendStreamingDataToClient(const muduo::net::TcpConnectionPtr &conn)
{
    // 这里是发送实际数据的逻辑，例如从数据库或其他数据源获取数据
    // ...

    // 发送示例数据（这里仅作为占位符）
    LOG_INFO << "Sending streaming data to client...";
    conn->send("Streaming data packet.");
}

int main()
{
    LOG_INFO << "pid = " << getpid();
    muduo::net::EventLoop loop;
    muduo::net::InetAddress listenAddr(8888);
    EchoServer server(&loop, listenAddr);
    server.start();
    loop.loop();
}